package com.dyc.caradvertisting.widget.trView;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.apkfuns.logutils.LogUtils;
import com.dyc.caradvertisting.R;
import com.dyc.caradvertisting.widget.utils.DividerItemWidthDecoration;
import com.jakewharton.rxbinding.view.RxView;
import com.njh.tools.base.BasePresenter;
import com.njh.tools.base.BaseViewHolder;
import com.njh.tools.base.RxManager;
import com.njh.tools.bean.BaseEntity;
import com.njh.tools.data.Data;
import com.njh.tools.view.LoadingLayout;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import rx.Observer;
import rx.functions.Action1;

/**
 * @author Administrator
 */
public class TRecyclerView<T extends BaseEntity.ListBean> extends LinearLayout {
    SwipeRefreshLayout swiperefresh;
    RecyclerView recyclerview;
    LoadingLayout mloading_view;
    private LinearLayoutManager mLayoutManager;
    private GridLayoutManager mGridLayoutManager;
    private Context context;
    private CoreAdapter<T> mCommAdapter = new CoreAdapter<>();
    private int begin = 0;
    private boolean isRefreshable = true, isHasHeadView = false, isEmpty = false;
    private BasePresenter model;
    public RxManager mRxManager = new RxManager();
    private Map<String, String> param = new HashMap<>();
    private boolean isSolve = false;
    private onTRecyclerViewListener onTRecyclerViewListener;
    private onOtherDataCall onOtherDataCall;

    public TRecyclerView.onTRecyclerViewListener getOnTRecyclerViewListener() {
        return onTRecyclerViewListener;
    }

    public void setOnTRecyclerViewListener(TRecyclerView.onTRecyclerViewListener onTRecyclerViewListener) {
        this.onTRecyclerViewListener = onTRecyclerViewListener;
    }

    public TRecyclerView(Context context) {
        super(context);
        init(context);
    }

    public TRecyclerView(Context context, AttributeSet att) {
        super(context, att);
        init(context);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mRxManager.clear();

    }

    public void init(Context context) {
        this.context = context;

        int res=R.layout.layout_list_recyclerview;
        if (null!=getOnTRecyclerViewListener()&&0!=getOnTRecyclerViewListener().getLaoutId()){
            res=getOnTRecyclerViewListener().getLaoutId();
        }
        View layout = LayoutInflater.from(context).inflate(res, null);
        layout.setLayoutParams(new LinearLayout.LayoutParams(
                android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                android.view.ViewGroup.LayoutParams.MATCH_PARENT));
        addView(layout);
//        ButterKnife.bind(this, layout);
        initView(context);
    }

    private void initView(Context context) {
        swiperefresh = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
        recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
        mloading_view=(LoadingLayout) findViewById(R.id.loading_view);
        swiperefresh.setColorSchemeResources(android.R.color.holo_blue_bright);
        swiperefresh.setEnabled(isRefreshable);
        swiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                reFetch();
            }
        });
        recyclerview.setHasFixedSize(true);
//        mLayoutManager = new LinearLayoutManager(context);
        mGridLayoutManager=   new GridLayoutManager(context, 2);
        recyclerview.setLayoutManager(mGridLayoutManager);
        recyclerview.setItemAnimator(new DefaultItemAnimator());
        recyclerview.setAdapter(mCommAdapter);
        recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
            protected int lastVisibleItem;

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (recyclerview.getAdapter() != null
                        && newState == RecyclerView.SCROLL_STATE_IDLE
                        && lastVisibleItem + 1 == recyclerview.getAdapter()
                        .getItemCount() && mCommAdapter.isHasMore)
                    fetch();
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int arg0, int arg1) {
                super.onScrolled(recyclerView, arg0, arg1);
                lastVisibleItem = mGridLayoutManager.findLastVisibleItemPosition();
            }
        });
        mRxManager.on(C.EVENT_DEL_ITEM, new Action1<Object>() {
            @Override
            public void call(Object o) {
                mCommAdapter.removeItem((Integer) o);
            }
        });
        mRxManager.on(C.EVENT_UPDATE_ITEM, (new Action1<Object>() {
            @Override
            public void call(Object arg0) {
                mCommAdapter.upDateItem(((UpDateData) arg0).i, ((UpDateData) arg0).oj);
            }
        }));
        mloading_view.setOnloadingListener(new LoadingLayout.OnloadingListener() {
            @Override
            public void onEmpty() {
                //点击重试
                reFetch();
            }

            @Override
            public void onError() {

            }
        });
    }

    /**
     * 设置recycleview的分割线
     *
     * @param dividerWidth 高度单位dp
     * @param dividerColor
     */
    public void setRvDivider(float dividerWidth, int dividerColor) {
        recyclerview.addItemDecoration
                (new DividerItemWidthDecoration(context, DividerItemWidthDecoration.VERTICAL_LIST,
                        dividerWidth, dividerColor));
    }

    public CoreAdapter getAdapter() {
        return mCommAdapter;
    }

    public void setRefreshing(boolean i) {
        swiperefresh.setRefreshing(i);
    }

    public TRecyclerView setIsRefreshable(boolean i) {
        isRefreshable = i;
        swiperefresh.setEnabled(i);
        return this;
    }

    public TRecyclerView setHeadView(Class<? extends BaseViewHolder> cla) {
        if (cla == null) {
            isHasHeadView = false;
            this.mCommAdapter.setHeadViewType(0, cla, null);
        } else
            try {
                Object obj = ((Activity) context).getIntent().getSerializableExtra(C.HEAD_DATA);
                int mHeadViewType = ((BaseViewHolder) (cla.getConstructor(View.class)
                        .newInstance(new View(context)))).getType();
                this.mCommAdapter.setHeadViewType(mHeadViewType, cla, obj);
                isHasHeadView = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        return this;
    }

    public TRecyclerView setHeadViewData(Object o) {
        this.getAdapter().setHeadViewData(o);
        return this;
    }

    public TRecyclerView setFooterView(Class<? extends BaseViewHolder> cla) {
        this.begin = 0;
        try {
            int mFooterViewType = ((BaseViewHolder) (cla.getConstructor(View.class)
                    .newInstance(new View(context)))).getType();
            this.mCommAdapter.setFooterViewType(mFooterViewType, cla);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    public void setEmpty() {
        if (!isHasHeadView && !isEmpty) {
            isEmpty = true;
            mloading_view.showEmpty();
            swiperefresh.setVisibility(View.GONE);
        }
    }

    public TRecyclerView setView(Class<? extends BaseViewHolder<T>> cla, BasePresenter basePresenter) {
        try {
            BaseViewHolder mIVH = ((BaseViewHolder) (cla.getConstructor(View.class)
                    .newInstance(new View(context))));
            int mType = mIVH.getType();
//            this.model = ((Class<T>) ((ParameterizedType) (cla
//                    .getGenericSuperclass())).getActualTypeArguments()[0])
//                    .newInstance();// 根据类的泛型类型获得model的实例
            this.model = basePresenter;
            this.mCommAdapter.setViewType(mType, cla);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    public void setSolved(boolean isSolved) {
        this.isSolve = isSolved;
    }

    public TRecyclerView setParam(String key, String value) {
        this.param.put(key, value);
        return this;
    }

    public Map<String, String> getParam() {
        return this.param;
    }

    public TRecyclerView setData(List<T> datas) {
        if (isEmpty) {
//            ll_emptyview.setVisibility(View.GONE);
            swiperefresh.setVisibility(View.VISIBLE);
        }
        mCommAdapter.setBeans(datas, 1);
        return this;
    }

    public void removeParamByKey(String key) {
        this.param.remove(key);
    }

    public void reFetch() {
        this.begin = 0;
        swiperefresh.setRefreshing(true);
        fetch();
    }

    public void fetch() {
        int temporary = begin;
        if (null != getOnTRecyclerViewListener()) {
            getOnTRecyclerViewListener().fetch(begin);
        }
        temporary++;
        if (isEmpty) {
            mloading_view.showLoading();
            swiperefresh.setVisibility(View.VISIBLE);
            isEmpty = false;
        }
//        setParam(Constants.KEY_PAGENO, temporary + "");
        final int finalTemporary = temporary;
            if (null != model) {
                mRxManager.add(model.getDate(getParam()).subscribe(new Observer<List<T>>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        netDataError(e);
                    }

                    @Override
                    public void onNext(List<T> subjects) {
                        netDataSuccess(finalTemporary, subjects);
                    }
                }));
            }else {
                mloading_view.showEmpty();
            }

    }

    public void netDataError(Throwable e) {
//        if (e instanceof ApiException) {
//            ToastUtil.getInstance().show(((ApiException) e).getMsg());
//        } else {
//            ToastUtil.getInstance().show(R.string.connect_fail);
//            LogUtils.wtf(e);
//        }
        setRefreshing(false);
        if (!mCommAdapter.isHasMore && mCommAdapter.mItemList == null) {
            mCommAdapter.setBeans(null, begin, 0);
        }
        setEmpty();
    }

    public void netDataSuccess(int finalTemporary, List<T> list) {
        begin = finalTemporary;
        swiperefresh.setRefreshing(false);
        mCommAdapter.setBeans(list, begin);
        if (begin == 1 && (list == null || list.size() == 0))
            setEmpty();
    }


    public class UpDateData {
        public int i;
        public T oj;

        public UpDateData(int i, T oj) {
            this.i = i;
            this.oj = oj;
        }
    }


    public class CoreAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        protected List<T> mItemList = new ArrayList<>();
        public boolean isHasMore = true;
        public int viewtype, isHasFooter = 1, isHasHader = 0, mHeadViewType;
        public Object mHeadData;
        public Class<? extends BaseViewHolder> mItemViewClass, mHeadViewClass, mFooterViewClass = CommFooterVH.class;
        public int mFooterViewType = CommFooterVH.LAYOUT_TYPE;

        public void setViewType(int i, Class<? extends BaseViewHolder> cla) {
            this.isHasMore = true;
            this.viewtype = i;
            this.mItemList = new ArrayList<>();
            this.mItemViewClass = cla;
            notifyDataSetChanged();
        }

        public void setHeadViewType(int i, Class<? extends BaseViewHolder> cla, Object data) {
            if (cla == null) {
                this.isHasHader = 0;
            } else {
                this.isHasHader = 1;
                this.mHeadViewType = i;
                this.mHeadViewClass = cla;
                this.mHeadData = data;
            }
        }

        public void setHeadViewData(Object data) {
            this.mHeadData = data;
            notifyDataSetChanged();
        }

        public void setFooterViewType(int i, Class<? extends BaseViewHolder> cla) {
            this.mFooterViewType = i;
            this.mFooterViewClass = cla;
            this.mItemList = new ArrayList<>();
            notifyDataSetChanged();
        }

        @Override
        public int getItemViewType(int position) {
            return isHasHader == 1 ? (position == 0 ? mHeadViewType
                    : (position + 1 == getItemCount() ? mFooterViewType : viewtype))
                    : (position + 1 == getItemCount() ? mFooterViewType : viewtype);
        }

        @Override
        public int getItemCount() {
            return mItemList.size() + isHasFooter + isHasHader;
        }

        public void setBeans(List<T> datas, int begin, int TotalCount) {
            if (datas == null) datas = new ArrayList<>();
            this.isHasMore = datas.size() >= C.PAGE_COUNT;
            if (begin > 1 && null != datas) {
                this.mItemList.addAll(datas);
            } else {
                if (null == datas) {
                    datas = new ArrayList<>();
                }
                this.mItemList = datas;
            }
            notifyDataSetChanged();
        }

        public void setBeans(List<T> datas, int begin) {
            if (datas == null) datas = new ArrayList<>();
            this.isHasMore = datas.size() >= C.PAGE_COUNT;
            if (begin > 1) {
                this.mItemList.addAll(datas);
            } else {
                this.mItemList = datas;
            }
            notifyDataSetChanged();
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            try {
                boolean isFoot = viewType == mFooterViewType;
                return (RecyclerView.ViewHolder) (viewType == mHeadViewType ? mHeadViewClass
                        .getConstructor(View.class).newInstance(
                                LayoutInflater.from(parent.getContext()).inflate(
                                        mHeadViewType, parent, false))
                        : (RecyclerView.ViewHolder) (isFoot ? mFooterViewClass : mItemViewClass)
                        .getConstructor(View.class).newInstance(
                                LayoutInflater.from(parent.getContext())
                                        .inflate(
                                                isFoot ? mFooterViewType
                                                        : viewtype, parent,
                                                false)));
            } catch (Exception e) {
                LogUtils.d("ViewHolderException", "onCreateViewHolder十有八九是xml写错了,哈哈");
                e.printStackTrace();
                return null;
            }
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ((BaseViewHolder) holder).setmPresenter(model);
            ((BaseViewHolder) holder).setSolve(isSolve);
            holder.itemView.setId(position);
            ((BaseViewHolder) holder).onBindViewHolder(holder.itemView,
                    position + 1 == getItemCount() ? (isHasMore ? new Object()
                            : null) : isHasHader == 1 && position == 0 ? mHeadData
                            : mItemList.get(position - isHasHader));
        }

        public void removeItem(int position) {
            mItemList.remove(position);
            notifyItemRemoved(position);
        }

        public void upDateItem(int position, T item) {
            mItemList.remove(position);
            mItemList.add(position, item);
            notifyItemChanged(position);
        }
    }

    public interface onTRecyclerViewListener {
        void fetch(int begin);
        int getLaoutId();
    }

    public interface onOtherDataCall {
        void dataFetch(Map<String, String> param, int finalTemporary);
    }

    public void setOtherData(onOtherDataCall onOtherDataCall) {
        this.onOtherDataCall = onOtherDataCall;
    }
}